﻿using System;
using System.Net;
using System.Web;
using System.Text;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;

namespace SBPweb.Relay.Processor
{

    public class WebResponseCloneHelper
    {

        #region Private fields

        private ProcessOutputHandler handler;

        #endregion

        #region Constructor logic

        public WebResponseCloneHelper()
        {
        }

        public WebResponseCloneHelper(ProcessOutputHandler processHandler)
        {
            this.handler = processHandler;
        }

        #endregion

        #region Events / delegates

        public delegate string ProcessOutputHandler(string output);

        #endregion

        #region Methods

        public void DeepCopy(HttpWebResponse source, HttpResponse destination)
        {
            destination.Clear();
            try
            {
                CopyHeaders(source.Headers, destination.Headers);
            }
            catch
            {
                //it is not IIS hosting
            }
            CopyCookies(source.Cookies, destination.Cookies);
            CopyContent(source, destination);
        }

        private void CopyHeaders(WebHeaderCollection headerSource, NameValueCollection headerDestination)
        {
            foreach (string header in headerSource)
            {
                headerDestination[header] = headerSource[header];
            }
        }

        private void CopyCookies(CookieCollection cookieSource, HttpCookieCollection cookieDestination)
        {
            foreach (Cookie cookie in cookieSource)
            {
                HttpCookie httpCookie = new HttpCookie(cookie.Name, cookie.Value);
                httpCookie.Domain = cookie.Domain;
                httpCookie.Expires = cookie.Expires;
                httpCookie.HttpOnly = cookie.HttpOnly;
                httpCookie.Path = cookie.Path;
                httpCookie.Secure = cookie.Secure;
                cookieDestination.Add(httpCookie);
            }
        }

        private void CopyContent(HttpWebResponse source, HttpResponse destination)
        {
            if (!string.IsNullOrEmpty(source.ContentEncoding))
            {
                destination.ContentEncoding = Encoding.GetEncoding(source.ContentEncoding);
            }
            else if (!string.IsNullOrEmpty(source.CharacterSet))
            {
                destination.ContentEncoding = Encoding.GetEncoding(source.CharacterSet);
            }
            destination.ContentType = source.ContentType;
            destination.StatusCode = (int)source.StatusCode;
            destination.StatusDescription = source.StatusDescription;

            CopyStream(source.GetResponseStream(), destination.OutputStream, destination.ContentEncoding);
        }

        private void CopyStream(Stream sourceStream, Stream destinationStream, Encoding encoding)
        {
            StreamReader reader = new StreamReader(sourceStream, encoding);
            string sourceText = reader.ReadToEnd();
            string destinationText = sourceText;

            if (handler != null)
            {
                destinationText = handler(sourceText);
            }

            StreamWriter writer = new StreamWriter(destinationStream, encoding);
            writer.Write(destinationText);

            destinationStream.Flush();
            /*
            byte[] buffer = new byte[sourceLength];
            int read;
            while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                destinationStream.Write(buffer, 0, read);
            }
            */
        }

        //public static void DeepCopy(HttpResponse source, HttpResponse destination)
        //{
        //}

        #endregion

    }
    
}